{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Load Data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "\n",
    "data = np.load(\"data/metrla.npy\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(34272, 207, 3)"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [],
   "source": [
    "num_steps=12"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Split Data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [],
   "source": [
    "T, N, _ = data.shape\n",
    "\n",
    "# Calculate the split points eg. 7:1:2\n",
    "train_end = int(T * 0.7)\n",
    "val_end = train_end + int(T * 0.1)\n",
    "\n",
    "# Split the dataset\n",
    "train = data[:train_end]\n",
    "# train = data\n",
    "test = data[val_end:]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get Historal Average"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create a dictionary to store lists of observations for each (tod, dow) pair\n",
    "history = {}\n",
    "# Iterate through the historical data to populate the history dictionary\n",
    "for i in range(train.shape[0]-num_steps-1):\n",
    "    \n",
    "    key = (train[i, 0, 1], train[i, 0, 2])  # (tod, dow) tuple\n",
    "    if key not in history:\n",
    "        history[key] = []\n",
    "        \n",
    "    # Collect observations for the next num_steps steps\n",
    "    future_values = train[i+1:i+num_steps+1,:,0]\n",
    "        \n",
    "    history[key].append(future_values)  # Collect and store future values\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [],
   "source": [
    "history_averages = {}\n",
    "\n",
    "# Calculate the average values for each (tod, dow) pair\n",
    "for k, v in history.items():\n",
    "    stacked_array = np.stack(v, axis=-1)\n",
    "    averages = np.mean(stacked_array, axis=-1)\n",
    "    history_averages[k] = averages"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2016"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(history_averages)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Test Data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [],
   "source": [
    "from metrics import compute_all_metrics\n",
    "\n",
    "import torch\n",
    "\n",
    "preds = []\n",
    "labels = []\n",
    "\n",
    "# Retrieve labels and predictions\n",
    "for i in range(test.shape[0]-num_steps-1):\n",
    "\n",
    "    key = (test[i, 0, 1], test[i, 0, 2])  # (tod, dow) tuple\n",
    "    \n",
    "    labels.append(test[i+1:i+num_steps+1,:,0])\n",
    "    preds.append(history_averages[key])\n",
    "    \n",
    "labels = np.stack(labels, axis=0)\n",
    "preds = np.stack(preds, axis=0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(6842, 12, 207)"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "preds.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "check mask value tensor(0.)\n",
      "Horizon 1, Test MAE: 7.1165, Test RMSE: 9.8372, Test MAPE: 0.1689\n",
      "Horizon 2, Test MAE: 7.1162, Test RMSE: 9.8369, Test MAPE: 0.1689\n",
      "Horizon 3, Test MAE: 7.1155, Test RMSE: 9.8361, Test MAPE: 0.1689\n",
      "Horizon 4, Test MAE: 7.1138, Test RMSE: 9.8347, Test MAPE: 0.1689\n",
      "Horizon 5, Test MAE: 7.1117, Test RMSE: 9.8335, Test MAPE: 0.1688\n",
      "Horizon 6, Test MAE: 7.1114, Test RMSE: 9.8332, Test MAPE: 0.1688\n",
      "Horizon 7, Test MAE: 7.1112, Test RMSE: 9.8330, Test MAPE: 0.1688\n",
      "Horizon 8, Test MAE: 7.1108, Test RMSE: 9.8326, Test MAPE: 0.1688\n",
      "Horizon 9, Test MAE: 7.1106, Test RMSE: 9.8324, Test MAPE: 0.1688\n",
      "Horizon 10, Test MAE: 7.1103, Test RMSE: 9.8320, Test MAPE: 0.1688\n",
      "Horizon 11, Test MAE: 7.1101, Test RMSE: 9.8318, Test MAPE: 0.1688\n",
      "Horizon 12, Test MAE: 7.1099, Test RMSE: 9.8315, Test MAPE: 0.1688\n",
      "Average Test MAE: 7.1123, Test RMSE: 9.8338, Test MAPE: 0.1689\n"
     ]
    }
   ],
   "source": [
    "labels = torch.Tensor(labels)\n",
    "preds = torch.Tensor(preds)\n",
    "\n",
    "# handle the precision issue when performing inverse transform to label\n",
    "mask_value = torch.tensor(0)\n",
    "if labels.min() < 1:\n",
    "    mask_value = labels.min()\n",
    "\n",
    "test_mae = []\n",
    "test_mape = []\n",
    "test_rmse = []\n",
    "print('check mask value', mask_value)\n",
    "\n",
    "# Calculate metrics\n",
    "for i in range(12):\n",
    "    res = compute_all_metrics(preds[:,i,:], labels[:,i,:], mask_value)\n",
    "    log = 'Horizon {:d}, Test MAE: {:.4f}, Test RMSE: {:.4f}, Test MAPE: {:.4f}'\n",
    "    print(log.format(i + 1, res[0], res[2], res[1]))\n",
    "    test_mae.append(res[0])\n",
    "    test_mape.append(res[1])\n",
    "    test_rmse.append(res[2])\n",
    "\n",
    "log = 'Average Test MAE: {:.4f}, Test RMSE: {:.4f}, Test MAPE: {:.4f}'\n",
    "print(log.format(np.mean(test_mae), np.mean(test_rmse), np.mean(test_mape)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "python38",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
